Rework the command surface: explicit targeting, delete verbs, workflow-grouped commands - #218
Conversation
The compute config it wrote is unsupported, so the wizard that created it goes with it. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Service commands drop the config-target positional and resolve the project from the invocation directory's link file alone. Agent setup status and the state directory no longer walk up to a config file. The local build-and-deploy path the config fed had no callers left, so app-provider loses deployApp with it. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
pnpm --recursive exec tsc --noEmit fails on packages/tsconfig, which has no typescript dependency. The root typecheck script (turbo run typecheck, per-package tsc --noEmit) already covers every TypeScript package. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Every service command that acts on an existing service now resolves it from --service (by name) or PRISMA_SERVICE_ID (by id, the domain-flow mechanics generalized), with the flag winning. Neither present settles SERVICE.TARGET_REQUIRED at exit 2, interactive terminals included: the interactive picker, the saved selection (rememberSelectedService, LocalStateStore.readSelectedApp/setSelectedApp/clearSelectedApp, the selectedByProject state shape), and service remove's selection cleanup are gone. Branch targeting is --branch only: the git-branch inference is deleted, read flows keep their "main" default and the domain flow keeps "production" with its production-only check. lib/git/local-branch.ts stays: controllers/app-env.ts (project env scope resolution, outside this change's scope) still imports it. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
- project/link.ts: linkDirectoryToProject's doc comment no longer claims init runs it; the export drops to in-file scope, its only use. - cli.ts and mount-coverage note that orm init keeps its path; only the top-level init (the compute config wizard) was removed (2026-08-21 PM review). - service/target.ts: resolveServiceProjectContext loses the projectDir option no caller passed. - state-dir.ts: resolveStateDir is synchronous and takes no signal; it only joins paths. Call sites adjusted. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
project delete, project env delete, postgres delete, postgres connection delete, service delete, and service domain delete replace their remove spellings everywhere: mount paths, source file names, exported symbols, result types (removed: true becomes deleted: true), help, examples, next actions, error copy, consent questions, progress step/status names, unit tests, and e2e describeCommand markers. No aliases or redirects for the old spellings. Error codes tied to these commands follow the verb: SERVICE.REMOVE_FAILED -> SERVICE.DELETE_FAILED, PROJECT_REMOVE_BLOCKED -> PROJECT_DELETE_BLOCKED (PROJECT.DELETE_BLOCKED). The unused legacy AppRemoveResult / AppDomainRemoveResult types are deleted. git disconnect, auth logout, bucket delete, and provider-internal removeApp/removeProject/removeDatabase/removeConnection/removeDomain helpers are untouched. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
- service logs --deployment decides scoped-vs-global on whether any service target was requested: PRISMA_SERVICE_ID now scopes the lookup exactly like --service (D2-1), with tests for the missing-target refusal, the service-scoped path and its not-in-this-service refusal, and the env-var-scoped path (D2-2). - ServiceShowResult.service and ServiceDeploymentListResult.service are non-null; the "not selected" presenter fallbacks are gone (D2-3). - ResolveProjectOptions.projectDir deleted; the invocation directory is the only pin location (D2-4). - User-facing copy no longer says "selected service" — the service is named, not selected (D2-5). - serviceTargetRequiredError keeps why to the cause; the PRISMA_SERVICE_ID alternative is its own nextActions entry so --json consumers see it (D2-6). Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
The mounted tree now equals the slice spec's acceptance tree: postgres restore moves under postgres backup, ref list|set|delete move under migration ref, migrate becomes db migrate, format becomes contract format, and composer's dev and deploy mount at the root. The composer group, composer destroy, composer log, and the build group (build logs and its sources and tests) are gone. No aliases or redirects for the old spellings. Both external families are re-wrapped with defineCommandFamily, keeping their configSection and docsBaseUrl. Composer keeps only deploy and dev, so mount-coverage's family-completeness check stays honest about the dropped commands. The ORM family passes its commands through but rewrites its shipped redirects: the migration ref entry is dropped (that spelling is live again, and mounting it with the redirect in place fails buildCli's collision check) and migration apply's replacement is respelled to db migrate. Root help examples end as auth login, project list, deploy. Coverage tables, group briefs (postgres backup now covers restore; migration ref is new), and the bin/orm-mount/postgres tests follow. The cli-engine redirect fixtures are synthetic and stay as they are. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
- Provider-layer failure summaries follow the verb rename: deleting a project, database, database connection, or custom domain now fails as "Failed to delete …", and the env branch-not-found why-text says delete. A postgres delete failure test pins the summary. - validateKey narrows to its reachable commands (add | update); the unreachable remove template branch goes with it. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Command tables and prose in both package READMEs, the root README, packages/cli/AGENTS.md, and the example READMEs now name the live tree: deploy and dev at the root, delete for the destroying commands, postgres backup restore, and the ORM groups without top-level migrate/format/init. command-principles drops init from the stable groups, respells migrate as db, and states the verb rule (delete destroys, remove detaches). The style/output guides use auth login as the first-run banner example; error-conventions drops the removed compute-config and init codes and follows the DELETE_BLOCKED / DELETE_FAILED renames; cli-engine-requirements respells db migrate and orm init; output-conventions loses the compute-config build settings bullet and respells the connection delete rows. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
…mand-review Each s2 parity record that documents a renamed or moved command gets a short dated entry (2026-08-21 PM review); command-inventory.md gets a pointer note. command-review.md is recreated in the 76a2c8a format against the new 86-command tree. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
- The wrapped ORM family respells the moved commands' shipped help examples to their mounted paths (contract format, db migrate, migration ref list|set|delete); a rendered-help test pins that no retired spelling survives in any of the five (D4-1). - The composer wrap subtracts destroy and log from the source family instead of selecting deploy and dev, so a command composer adds upstream reaches the wrapped family and mount-coverage flags it until the shell mounts it (D4-2). Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
|
Important Review skippedToo many files! This PR contains 149 files, which is 49 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (149)
You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
- orm init joins the ORM mount respellings: its six shipped help examples now render as orm init, pinned by a sixth row in the rendered-help test and init in the retired-spelling check (D5-1). - The output gallery drops its two init shots (init --help and the hono wizard run) and the wizard's caption panel; both would now capture an unknown-command error (D5-2). Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Review of the grammar-cleanup branch surfaced that removing the git-branch inference left most service commands with no way to reach a service on a non-default branch, and that many help examples and next-action hints named invocations the new parameter-only grammar refuses. - service show/open/logs and every service deployment verb take --branch, threaded into the existing branchName resolution, so preview-branch services and deployments are reachable again. - An empty --branch is refused centrally in the target resolvers instead of only in service delete, and the error's copy no longer describes the deleted git inference. - Every shipped help example and next-action hint that named a service command now carries --service — interpolated where the name is in scope, a <name> placeholder where it is not — and projectDeleteBlockedError suggests the flags-only service delete shape. After service delete, the next action is service list, since nothing service-scoped can run. - The knownLiveDeployment local state had no writers left: the schema, its store methods, and service delete's cleanup pass are gone. - resolveServiceReleaseState had become a passthrough around resolveServiceReadState; the callers use the read state directly. - types/app.ts kept ~18 interfaces nothing produced; the two live domain types moved into service/results.ts as ServiceDomainStatus and ServiceDomainDnsRecord. - New/edited markdown prose is unwrapped to one line per paragraph. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
…oyments by id alone Operator ruling on the review round: any command that operates on a subject resource takes that resource's identifier as its first positional argument — the established CLI convention — and flags only scope or qualify. Recorded as "Subjects are positional" in docs/product/command-principles.md and as a dated amendment in the slice spec. - service show/open/logs/delete and service deployment list/rollback take the service name as an optional positional (PRISMA_SERVICE_ID stays as the env fallback; neither present is still the SERVICE.TARGET_REQUIRED refusal, its copy respelled). - service deployment promote/start/stop/delete and service logs --deployment are targeted by the globally-unique deployment id alone, resolved through the same global lookup service deployment show always used (a shared resolveDeploymentSubject). They take no --service, --project, or --branch, and their results drop projectId, matching deployment show. SERVICE.DEPLOYMENT_OUTSIDE_PROJECT is gone with the project check it belonged to. - project show takes the project as an optional positional instead of --project, with a retryCommand override so the shared project-setup hint stops suggesting a flag the command no longer has. - Domain commands keep --service as a scope flag: their positional is the hostname, and the management API has no global hostname lookup. The API's missing deployment-to-service lookup (each id-targeted run pays a project-by-project scan) is recorded in the deferred ledger. - Help examples, error hints, unit tests, and the e2e suite follow the new grammar. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Operator ruling: extend parameters-only targeting to project env. A
bare `project env list` now lists the overview of every scope instead
of resolving the checkout's branch against the platform; --role and
--branch are the only scope selectors, as they already were for
add/update/delete. readLocalGitBranch and lib/git/local-branch.ts are
deleted — nothing else imported them — and the "local-git" target
source is gone from the list result shape.
Also sharpened the deferred-ledger entry on deployment lookups with
what the API actually returns: GET /v1/deployments/{id} omits the
parent appId, which is why the CLI scans for the owner. The fix
belongs in pdp-control-plane's deployment representation.
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Operator ruling: the env var existed for the headless app deploy flow, which this PR already deleted; the domain commands were its only surviving reader, by accident rather than decision. Project targeting is --project and the link file. The envProjectId option and the allowEnvProjectId split between resolveProjectTarget and inspectProjectBinding collapse with it, and the "env" project source leaves the result types. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
…ys so pdp-control-plane ADR-012 retires "Deployment" as a noun — a deploy produces a Version — and the CLI adopts it now, pre-rc, before any release teaches users the retired word. - Commands: service deployment list|show|promote|rollback|start|stop| delete mount as service version …; service logs --deployment becomes --version-id (the engine reserves the flag name "version" for the shared --version flag). - JSON contract: deployment→version, deployments→versions, deploymentId→versionId, liveDeployment→liveVersion, recentDeployments→recentVersions, previousLiveDeploymentId→ previousLiveVersionId, and liveDeploymentId→liveVersionId on list entries. Progress steps stop-deployments/delete-deployments become stop-versions/delete-versions. - Error codes: SERVICE.DEPLOYMENT_*→SERVICE.VERSION_*, NO_DEPLOYMENTS→NO_VERSIONS, NO_PREVIOUS_DEPLOYMENT→ NO_PREVIOUS_VERSION, LIVE_DEPLOYMENT_UNKNOWN→LIVE_VERSION_UNKNOWN. - Copy: help and error prose says "service version" (qualified, per the ADR); example ids use the real cpv_ prefix. - The wire layer deliberately keeps platform vocabulary until the platform's own coordinated rename: /v1/deployments paths, compute-sdk names, appId, and the adapter in lib/app/app-provider.ts, which is the seam where the two vocabularies meet. Recorded in the ledger. - docs/product/command-principles.md's noun table now says service and version; READMEs, the slice-spec amendment, tests, and the e2e suite follow. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
The create/show e2e asserted liveDeploymentId, liveDeployment, and recentDeployments, which the ADR-012 rename respelled to liveVersionId, liveVersion, and recentVersions — caught by the credentialed CI run, which the local suite cannot reach. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Operator ruling: no env-var targeting, and no hidden second targeting mode. PRISMA_SERVICE_ID matched by id while the argument matched by name — the same string meant different things depending on where you wrote it — and the workflow it served (the headless deploy pipeline) no longer exists. The service argument itself now carries the capability with one visible rule: the stable platform id is primary, the display name is the secondary fallback, and an id match always wins, so a service named like another service's id can never shadow it. The project and database matchers get the same precedence (both previously reported a name-vs-id collision as ambiguous or first-match). The rule is recorded under "Subjects are positional" in docs/product/command-principles.md, and the spec carries a dated amendment superseding the env-fallback clause. The env-specific SERVICE.SELECTION_INVALID variant and the "set PRISMA_SERVICE_ID" advice are gone; briefs read "Service id or name". Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
## Linked issue n/a — requested by brief (prisma-cli PR [#218](prisma/prisma-cli#218) mounts this family and currently re-wraps it; that wrapper is deleted once this ships). ## At a glance ```ts const commands: Readonly<Record<string, AnyCommand>> = { 'contract emit': contractEmitCommand, 'contract format': formatCommand, // … 'db migrate': migrateCommand, // … 'migration ref delete': refDeleteCommand, 'migration ref list': refListCommand, 'migration ref set': refSetCommand, // … 'orm init': initCommand, }; ``` Before this PR the same six commands were keyed `format`, `migrate`, `ref delete|list|set`, and `init` — the retired standalone grammar — and prisma-cli respelled them at mount time with string arithmetic (`ORM_MOUNT_RESPELLINGS` / `respellMovedOrmCommands`). ## Decision The ORM command family ships the unified CLI's grammar directly, so the prisma-cli wrapper can be deleted: 1. The six moved commands are rekeyed to their unified mount paths (`contract format`, `db migrate`, `migration ref list|set|delete`, `orm init`), and their help examples spell those paths. 2. The `migration ref` → `ref …` redirect is deleted (that spelling is a live mount again); `migration apply`'s replacement is respelled to `{bin} db migrate --to <contract>`. The four `migration status` flag redirects were already correct. 3. Every shipped runtime string that references a command — error `fix` prose, `why` text, typed next actions, retry commands — is swept for retired spellings and hardcoded bin names (`prisma-cli`, `prisma-next`, `prisma`). Command references now use the `{bin}` placeholder with the unified grammar, per the convention on `NextAction` in `packages/1-framework/0-foundation/utils/src/structured-error.ts`. This sweep spans the cli package plus `@internal/migration-tools` and `@internal/errors`, whose copy bundles into the toolchain's dist. 4. This repo's stand-in bin (`createBinCommands` in `packages/1-framework/3-tooling/cli/src/orm/cli.ts`) mounts the family at the same paths, so examples and e2e tests exercise the commands the way the unified CLI serves them. 5. The user-facing skills (`skills/prisma-8`, `skills/journey-tests`), current docs (glossary, Telemetry, Serverless guide, the cli README), and three example package scripts are respelled to the same grammar. ## How it fits together 1. **The family speaks the mount grammar** — `packages/1-framework/3-tooling/cli/src/orm/family.ts` keys the six moved commands at their unified paths and drops the now-colliding `migration ref` redirect. The key set matches prisma-cli's `mount-coverage.test.ts` expected tree exactly (unmoved commands unchanged, `lsp` stays top-level). 2. **The stand-in bin mirrors the host** — `src/orm/cli.ts` mounts the same paths, replaces the top-level `ref` help group with `migration ref`, and updates the `orm` group text that claimed the other commands mount at the top level. 3. **Help examples respell themselves** — each moved command's `help.examples` spell the mounted path (`db migrate --show`, `migration ref set staging 4cb4256`, …), so prisma-cli's `respellHelpExamples` has nothing left to do. 4. **Runtime copy uses `{bin}` + unified grammar** — e.g. `src/utils/migrate-failure.ts` now says ``Fix the issue and re-run `{bin} db migrate --to <contract>` ``, and `@internal/migration-tools`' ref errors say `{bin} migration ref set <name> <hash>`. The one deliberate exception: `orm init`'s scaffold and spawn keep the literal `prisma-cli` where they name the real project-local binary the `@prisma/cli` package installs (its bin genuinely is `prisma-cli`). ## Reviewer notes - The bulk of the diff is a mechanical string sweep; the semantic core is `family.ts`, `cli.ts`, and the six command files' help examples. - `commandName`/`invocation` strings threaded into why-copy (`'db migrate'`, `'db sign'`, …) were respelled too — they render in sentences like "db migrate reads the emitted contract…". - The "known related defect" in the brief (`orm init` scaffolding `prisma-next.config.ts`) is already fixed on main — `src/orm/init-scaffold.ts` writes `prisma.config.ts`. Nothing to do here. - Version-pinned upgrade skills (`skills/prisma-next-upgrade/upgrades/*`, `skills/prisma-8-extension-upgrade/upgrades/*`) still say `prisma-next migrate` etc. deliberately: they document already-released versions where that grammar was correct. - `test/integration/test/utils/cli-test-helpers.ts` lost its `init` → `orm init` remap — the family key now is the mount path, so the helper mounts the family verbatim. - `docs/releases/*` and `docs/design/*` keep old spellings as history. ## Behavior changes & evidence - **Help renders the mounted spelling.** `--help` for the six moved commands shows `contract format`, `db migrate`, `migration ref …`, `orm init` examples ([src/orm/migrate.ts](packages/1-framework/3-tooling/cli/src/orm/migrate.ts), [src/orm/ref/set.ts](packages/1-framework/3-tooling/cli/src/orm/ref/set.ts); evidence: [test/orm/cli.test.ts](packages/1-framework/3-tooling/cli/test/orm/cli.test.ts)). - **`migration apply` redirects to `db migrate`.** The retired verb answers with `{bin} db migrate --to <contract>` ([src/orm/family.ts](packages/1-framework/3-tooling/cli/src/orm/family.ts); evidence: the redirect assertions in [test/orm/cli.test.ts](packages/1-framework/3-tooling/cli/test/orm/cli.test.ts)). - **Error remediation runs verbatim in the unified tree.** Fix strings and next actions name `{bin} db migrate`, `{bin} migration ref set …`, `{bin} orm init` ([src/utils/cli-errors.ts](packages/1-framework/3-tooling/cli/src/utils/cli-errors.ts), [migration/src/refs.ts](packages/1-framework/3-tooling/migration/src/refs.ts); evidence: [test/cli-errors.test.ts](packages/1-framework/3-tooling/cli/test/cli-errors.test.ts), [test/integration/test/cli.migrate-external-space.e2e.test.ts](test/integration/test/cli.migrate-external-space.e2e.test.ts), which parses the presented remediation and executes it). - **The built dist carries no retired spelling.** A sweep of `dist/*.mjs` shows every command reference as `{bin} <unified path>`; the only remaining `prisma-cli` strings name the real project-local binary the init flow spawns. ## Verification - `pnpm build` — 85/85 tasks. - `pnpm lint` — 99/99 tasks (includes the no-bare-cast ratchet and rules/skills checks). - `pnpm lint:skills` — all skills valid. - `pnpm test:packages` — 15374 passed, 0 failed. - `pnpm test:integration` — 2052 passed; the only failure is `test/ports/prisma/functional/issues-28192-pg-historical-dates` (a 28-second local-mean-time offset on year-120 timestamptz values — machine-timezone dependent, pre-existing, untouched by this change). - `pnpm test:e2e` — 115 passed. ## Follow-ups Downstream in prisma-cli (out of this PR's scope, recorded in its ledger): bump the `@prisma/orm-toolchain` pin, delete `ORM_MOUNT_RESPELLINGS` / `respellHelpExamples` / `respellMovedOrmCommands` and the redirect filter/rewrite in `cli.ts`, and flip `orm-mount.test.ts`'s respell assertions to prove upstream stays clean. ## Alternatives considered - **Keep the family keys and let prisma-cli keep respelling.** Rejected: we control both packages; the wrapper is string arithmetic over shipped metadata, fails silently when either side drifts, and forces prisma-cli to filter redirects to satisfy its collision check. - **Rekey the family but keep the standalone bin on the old grammar via a key map.** Rejected: the stand-in bin exists to mirror the real host, and a second grammar would keep the retired spellings alive in examples, recordings, and e2e tests. - **Hardcode `prisma` in runtime copy instead of `{bin}`.** Rejected: `NextAction.command` documents the `{bin}` convention repo-wide, and the family runs under whatever name the hosting shell registers. ## Skill update `skills/prisma-8` (SKILL.md + references), `skills/journey-tests`, and `skills/DEVELOPING.md` are respelled to the unified grammar in this PR. Version-pinned upgrade skills are intentionally unchanged (they document old versions). ## Checklist - [x] All commits are signed off (`git commit -s`) per the [DCO](../CONTRIBUTING.md#developer-certificate-of-origin-dco). - [x] I read [CONTRIBUTING.md](../CONTRIBUTING.md) and the change is scoped to one logical concern. - [x] Tests are updated. - [ ] The PR title is in `TML-NNNN: <sentence-case title>` form — no Linear ticket was resolvable from the branch, brief, or commits; retitle once the ticket is known. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Updated CLI command structure: migrations use `db migrate`, references use `migration ref`, formatting uses `contract format`, and initialization uses `orm init`. * Command guidance now adapts to the active executable name. * **Documentation** * Updated guides, examples, quickstarts, and workflows with current command names and usage. * Standardized CLI references across migration, build, runtime, and troubleshooting documentation. * **Tests** * Updated automated coverage for renamed commands and improved remediation messages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
composer-cli 0.12.0 retired destroy/log (composer#253) and orm-toolchain 8.0.0-rc.5 rekeyed its family to the mount paths and fixed its redirect table (prisma#30102), so the shell's re-wrapping — the destroy/log subtraction, the help-example respelling, and the redirect filter/rewrite — is deleted. Both families mount exactly as their packages ship them: the mount table reads the upstream keys, and wrapCommandFamily, toRedirectSpec, COMPOSER_DROPPED_COMMANDS, ORM_MOUNT_RESPELLINGS, respellHelpExamples, and respellMovedOrmCommands are gone. orm-mount.test.ts's example and redirect assertions keep their strings and flip their meaning: they now prove upstream stays clean rather than that a wrapper repaired it. The platform family's stale serviceDeployment* internal keys are renamed serviceVersion* in passing. Both new pins peer @prisma/cli-engine 0.2.0, matching the workspace engine. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
This PR reshapes the CLI's command surface in one pass. At a glance, what a user types changes like this:
prisma initprisma project link/project create)prisma service removeprisma service delete <name>prisma postgres restoreprisma postgres backup restoreprisma ref set stagingprisma migration ref set stagingprisma migrate/prisma formatprisma db migrate/prisma contract formatprisma composer dev/composer deployprisma dev/prisma deployprisma service show(interactive service picker)prisma service show <name>(no picker)The decision: the CLI is pre-rc, so we owe the old spellings nothing. Every old spelling above now gets the standard unknown-command error — no aliases, no redirects, no deprecation window. That single decision is what keeps this PR mechanical: commands move or rename, and every string that names them (help, examples, error copy, "next action" hints, tests, docs) follows.
Three ideas drive the new shape:
.prisma/local.json). Commands that act on a subject resource take its identifier as the first positional argument (service show <name>, withPRISMA_SERVICE_IDas the env fallback; the argument wins) plus scope flags like--branch <name>; commands targeted by a globally-unique version id (service version promote|start|stop|delete <id>,service logs --version-id <id>) need nothing else at all. Missing target → a structuredSERVICE.TARGET_REQUIREDerror, exit 2, before any network call — even in an interactive terminal. The interactive picker, the remembered per-project selection, and the "use the current git branch" inference are gone. What runs is what was named, which is what makes runs reproducible for humans and scriptable for agents.deletedestroys,removedetaches. Six commands that permanently destroy resources were calledremove; they are nowdeleteend to end — help, consent questions, JSON output (removed→deleted), error codes (…REMOVE_FAILED→…DELETE_FAILED).git disconnectandauth logoutstay: they detach.composerandbuilddisappear as groups:devanddeployare the root-level verbs of the main workflow (this also fixes their shipped help examples, which already readprisma deploy …),composer destroy/logare dropped, and the deprecated platform build runner'sbuild logsgoes with its group.reffolds intomigration ref;restoresits underpostgres backupbecause it acts on a backup.How it's implemented. The shell owns the command tree in
packages/cli/src/cli.ts, so most of the diff is that mount table plus strings. The composer and ORM command families ship from their own packages and mount exactly as shipped — no wrapping: composer-cli 0.12.0 retireddestroy/logupstream, and orm-toolchain 8.0.0-rc.5 keys its family by the mount paths with a correct redirect table, so the family keys ARE the mount paths and the shell adds nothing.Also removed outright: the deprecated
prisma.compute.ts/.jsonconfig and everything that read it — theinitwizard, the config-driven service targeting positional, theSERVICE.COMPUTE_CONFIG_*error codes, and the agent-status config probe (~5k lines).Guard rails. The grammar-completeness test (
packages/cli/tests/mount-coverage.test.ts) asserts the mounted tree equals the agreed 86-command tree, and runs before publish. Docs, both package READMEs, and the product convention docs (including the new delete/remove verb rule) are updated in the same PR. Verified:pnpm typecheck,pnpm lint, unit suites (841 + 11 passed),pnpm check:grammar; e2e runs in CI (local run skipped without credentials).Alternatives considered.
🤖 Generated with Claude Code
ADR-012 vocabulary (added in review). pdp-control-plane ADR-012 retires "Deployment" as a noun — a deploy produces a Version — so this PR also lands that rename on the CLI surface before any rc teaches users the retired word:
service deployment *isservice version *, JSON fields and error codes respell (deployment→version,SERVICE.DEPLOYMENT_*→SERVICE.VERSION_*, …), and prose says "service version". The wire layer (/v1/deployments, compute-sdk names,appId) deliberately keeps platform vocabulary until the platform's own coordinated rename; the adapter inlib/app/app-provider.tsis the seam where the two meet.